#include <iostream>
#include <fstream>
#include <string>
#include <map>
#include "struct.hpp"

#include "pugi/pugixml.hpp"

using namespace std;

std::string MemberValue(void* structPtr, int offset, const std::string &type)
{
    char* valuePtr = (char*)structPtr+offset;
    if(type == "char") return std::to_string(*(char*)(valuePtr));
    if(type == "unsigned char") return std::to_string(*(unsigned char*)(valuePtr));
    if(type == "short") return std::to_string(*(short*)(valuePtr));
    if(type == "unsigned short") return std::to_string(*(unsigned short*)(valuePtr));
    if(type == "int") return std::to_string(*(int*)(valuePtr));
    if(type == "unsigned int") return std::to_string(*(unsigned int*)(valuePtr));
    if(type == "long") return std::to_string(*(long*)(valuePtr));
    if(type == "unsigned long") return std::to_string(*(unsigned long*)(valuePtr));
    if(type == "float") return std::to_string(*(float*)(valuePtr));
    if(type == "double") return std::to_string(*(double*)(valuePtr));
    if(type == "long long") return std::to_string(*(long long*)(valuePtr));
    if(type == "long double") return std::to_string(*(long double*)(valuePtr));

    return std::string("NUL");
}

void PrintStruct(void* structPtr, const char* structXml)
{
    std::ofstream ofs("csvfile.csv", std::ios_base::binary);


    pugi::xml_document doc;
    auto ret = doc.load_file(structXml);
    if(!ret)
    {
        std::cout << ret.description() << std::endl;
        return;
    }

    auto root = doc.first_child();

    // <leaf path="/a" offset="0" length="4" type="int" />
    for(auto n: root.children("leaf"))
    {
        std::string path = n.attribute("path").as_string();
        int offset = n.attribute("offset").as_int();
        int length = n.attribute("length").as_int();
        std::string type = n.attribute("type").as_string();
        std::cout << boolalpha ;
        std::cout << path << "," << type << "," << MemberValue(structPtr, offset, type) << std::endl;
        ofs << path << ","<< type << "," << MemberValue(structPtr, offset, type) << std::endl;
    }

    ofs.close();
}


void main(void)
{
    S s = {1,'a', 5.f, 3.14};
    PrintStruct(&s, "output.xml");
}